#include "portal_user.h"
#include "portal_md5.h"
#include "portal_http.h"

struct portal_user_s *portal_find_user(IPADDRTYPE ip, IPADDRTYPE6 *ipv6, int af)
{
    struct portal_user_s *user;

    if (af == AF_INET) {
        list_for_each_entry(user, &portal_args.v4_user, lst, struct portal_user_s) {
            if (user->ipv4 == ip) {
                return user;
            }
        }
    } else {
        list_for_each_entry(user, &portal_args.v6_user, lst, struct portal_user_s) {
            if (!memcmp(&user->ipv6, ipv6, sizeof(IPADDRTYPE6))) {
                return user;
            }
        }
    }

    return NULL;
}

struct portal_user_s *portal_find_user_by_id(char *sessionid)
{
    struct portal_user_s *user;

    list_for_each_entry(user, &portal_args.v4_user, lst, struct portal_user_s) {
        if (!memcmp(user->sessionid, sessionid, 32)) {
            return user;
        }
    }
    list_for_each_entry(user, &portal_args.v6_user, lst, struct portal_user_s) {
        if (!memcmp(user->sessionid, sessionid, 32)) {
            return user;
        }
    }

    return NULL;
}

void portal_del_user(struct portal_user_s *user)
{
    PORTAL_DEBUG("del user %x", user->ipv4);
    list_del_init(&user->lst);
    portal_del_user_listen_fd(&user->sock_lst);
    free(user);
}

void portal_add_bindmac_user(uchar *mac, char *username, char *password)
{
    struct bind_user_s *user;

    list_for_each_entry(user, &portal_args.bind_lst, lst, struct bind_user_s) {
        if (!memcmp(mac, user->mac, 6)) {
            return;
        }
    }

    user = malloc(sizeof(struct bind_user_s));
    if (!user) {
        return;
    }
    memset(user, 0, sizeof(*user));
    list_add_tail(&user->lst, &portal_args.bind_lst);
    memcpy(user->mac, mac, 6);
    strcpy(user->username, username);
    strcpy(user->password, password);
    PORTAL_DEBUG("add mac %02X-%02X-%02X-%02X-%02X-%02X bind user name %s, password %s",
                 (unsigned int)mac[0], (unsigned int)mac[1], (unsigned int)mac[2],
                 (unsigned int)mac[3], (unsigned int)mac[4], (unsigned int)mac[5], username, password);
}

bool portal_find_bindmac(uchar *mac)
{
    struct bind_user_s *user;

    list_for_each_entry(user, &portal_args.bind_lst, lst, struct bind_user_s) {
        if (!memcmp(mac, user->mac, 6)) {
            return TRUE;
        }
    }

    return FALSE;
}

bool portal_bindmac_get_userinfo(struct portal_user_s *portal_user)
{
    struct bind_user_s *user;

    PORTAL_DEBUG("add mac %02X-%02X-%02X-%02X-%02X-%02X bind user",
                 portal_user->mac[0], portal_user->mac[1], portal_user->mac[2],
                 portal_user->mac[3], portal_user->mac[4], portal_user->mac[5]);
    list_for_each_entry(user, &portal_args.bind_lst, lst, struct bind_user_s) {
        if (!memcmp(portal_user->mac, user->mac, 6)) {
            snprintf(portal_user->username, sizeof(portal_user->username), "%s", user->username);
            snprintf(portal_user->password, sizeof(portal_user->password), "%s", user->password);
            PORTAL_DEBUG("found %s %s", portal_user->username, portal_user->password);
            return TRUE;
        }
    }

    return FALSE;
}

void portal_bindmac_upd_userinfo(struct portal_user_s *portal_user)
{
    struct bind_user_s *user;

    PORTAL_DEBUG("add mac %02X-%02X-%02X-%02X-%02X-%02X bind user",
                 portal_user->mac[0], portal_user->mac[1], portal_user->mac[2],
                 portal_user->mac[3], portal_user->mac[4], portal_user->mac[5]);
    list_for_each_entry(user, &portal_args.bind_lst, lst, struct bind_user_s) {
        if (!memcmp(portal_user->mac, user->mac, 6)) {
            snprintf(user->username, sizeof(user->username), "%s", portal_user->username);
            snprintf(user->password, sizeof(user->password), "%s", portal_user->password);
            PORTAL_DEBUG("found %s %s", user->username, portal_user->password);
        }
    }
}


void portal_make_sessionid(struct portal_user_s *user)
{
    char input[256], output[16];
    int len, i;
    char tmp[10];

    memset(input, 0, sizeof(input));
    memset(output, 0, sizeof(output));
    memset(user->sessionid, 0, sizeof(user->sessionid));
    if (user->af == AF_INET) {
        memcpy(input, &user->ipv4, sizeof(IPADDRTYPE));
        memcpy(input + sizeof(IPADDRTYPE), &user->nasip, sizeof(IPADDRTYPE));
        len = sizeof(IPADDRTYPE) * 2;
    } else {
        memcpy(input, &user->ipv6, sizeof(IPADDRTYPE6));
        memcpy(input + sizeof(IPADDRTYPE6), &user->nasip, sizeof(IPADDRTYPE));
        len = sizeof(IPADDRTYPE) + sizeof(IPADDRTYPE6);
    }
    portal_md5(input, len, output);
    for (i = 0; i < sizeof(output); i++) {
        sprintf(tmp, "%02x", output[i]);
        strcat(user->sessionid, tmp);
    }
}
